package com.keson.blueconfig;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import java.lang.reflect.Method;

public class MainActivity extends Activity{

    /** Called when the activity is first created. */
    private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    private BluetoothClient bluetoothClient;
    private BluetoothReceiver bluetoothReceiver;
    private Spinner ethType;
    private TextView ethIp;
    private TextView ethGateway;
    private TextView ethDns1;
    private TextView ethDns2;
    private EditText clientNo;
    private EditText city;
    private EditText longitude;
    private EditText latitude;
    private EditText openTime;
    private EditText closeTime;
    private EditText adVolume;
    private EditText alertVolume;
    private EditText orgName;
    private EditText intensity;
    private JSONObject info;
    private JSONObject config;
    private TextView ethinfo;
    private LocationManager lm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkBTPermission();
        SDKInitializer.initialize(getApplicationContext());
        ethType = findViewById(R.id.ethType);
        ethIp = findViewById(R.id.ethIp);
        ethGateway = findViewById(R.id.ethGateway);
        ethDns1 = findViewById(R.id.ethDns1);
        ethDns2 = findViewById(R.id.ethDns2);
        ethinfo = findViewById(R.id.ethinfo);

        clientNo = ((EditText)findViewById(R.id.clientNo));
        city = ((EditText)findViewById(R.id.city));
        longitude = ((EditText)findViewById(R.id.longitude));
        latitude = ((EditText)findViewById(R.id.latitude));
        openTime = ((EditText)findViewById(R.id.openTime));
        closeTime = ((EditText)findViewById(R.id.closeTime));
        adVolume = ((EditText)findViewById(R.id.adVolume));
        alertVolume = ((EditText)findViewById(R.id.alertVolume));
        orgName = ((EditText)findViewById(R.id.orgName));
        intensity = ((EditText)findViewById(R.id.intensity));

        bluetoothClient= new BluetoothClient(new BaseBluetooth.BTListener() {
            @Override
            public void socketNotify(int state, Object obj) {
                System.out.println(state+":"+String.valueOf(obj));
                if(state==BaseBluetooth.BTListener.MSG_RECEIVED){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this,"获取成功",Toast.LENGTH_LONG).show();
                        }
                    });
                    JSONObject json = JSONObject.parseObject(String.valueOf(obj));
                    switch (json.getString("action")){
                        case "answerWifiInfo":
                            ((TextView)findViewById(R.id.wifiinfo)).setText(/*"wifi名称:"+json.getString("ssid")+*/"wifi网络状态"+(json.getBooleanValue("net")?"正常":"异常"));
                            break;
                        case "answerEthInfo":
                            ethType.setSelection(json.getString("type").equals("static")?1:0,true);
                            ethIp.setText(json.getString("ip"));
                            ethGateway.setText(json.getString("gateway"));
                            ethDns1.setText(json.getString("dns1"));
                            ethDns2.setText(json.getString("dns2"));
                            ethinfo.setText(json.getBooleanValue("net")?"有线网络状态正常":"有线网络状态异常");
                            break;
                        case "answerDevStatus":
                            TextView devStatus = ((TextView) findViewById(R.id.devStatus));
                            devStatus.setText("设备信息：");
                            for (String key :json.keySet()) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        devStatus.setText(devStatus.getText().toString()+"\n"+key+"："+json.getString(key));
                                    }
                                });
                            }
                            break;
                        case "answerConfig":
                            info = json.getJSONObject("info");
                            config = json.getJSONObject("config");
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    clientNo.setText(info.getString("clientNo"));
                                    city.setText(info.getString("city"));
                                    longitude.setText(config.getString("longitude"));
                                    latitude.setText(config.getString("latitude"));
                                    openTime.setText(config.getString("openTime"));
                                    closeTime.setText(config.getString("closeTime"));
                                    adVolume.setText(config.getString("adVolume"));
                                    alertVolume.setText(config.getString("alertVolume"));
                                    orgName.setText(config.getString("orgName"));
                                    intensity.setText(config.getString("intensity"));
                                }
                            });
                            break;
                        case "ok":
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this,"配置成功",Toast.LENGTH_LONG).show();
                                }
                            });
                            break;
                        case "error":
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this,"配置失败，请检查参数格式是否包含空格等特殊字符",Toast.LENGTH_LONG).show();
                                }
                            });
                            break;
                    }
                }else if(state==BaseBluetooth.BTListener.DISCONNECTED){
//                    ((TextView)findViewById(R.id.result)).setText("设备已断开");
                }
            }
        });

        findViewById(R.id.scan).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                found = false;
                for (BluetoothDevice bluetoothDevice:bluetoothAdapter.getBondedDevices()) {
                    System.out.println("?????? "+bluetoothDevice.getName());
                    if("Android Bluedroid".equals(bluetoothDevice.getName())){
//                bluetoothClient.connect(bluetoothDevice);
                        System.out.println("?????? 取消配对");
                        unpairDevice(bluetoothDevice);
                        break;
                    }
                }

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if (!bluetoothAdapter.isEnabled())
                        {
                            bluetoothAdapter.enable();//异步的，不会等待结果，直接返回。
                            try {
                                Thread.sleep(5000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        ((TextView)findViewById(R.id.result)).setText("正在搜索设备");
                        bluetoothAdapter.startDiscovery();
                    }
                }).start();
            }
        });

        findViewById(R.id.wifibutton).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
                 if(((TextView)findViewById(R.id.result)).getText().equals("已连接设备")){
                     findViewById(R.id.wificonfig).setVisibility(LinearLayout.VISIBLE);
                     findViewById(R.id.ethconfig).setVisibility(LinearLayout.GONE);
                     findViewById(R.id.status).setVisibility(LinearLayout.GONE);
                     findViewById(R.id.config).setVisibility(LinearLayout.GONE);
                 }else {
                     Toast.makeText(MainActivity.this,"请先连接设备",Toast.LENGTH_LONG).show();
                 }
             }
         });
        findViewById(R.id.ethbutton).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if(((TextView)findViewById(R.id.result)).getText().equals("已连接设备")){
                    findViewById(R.id.wificonfig).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.ethconfig).setVisibility(LinearLayout.VISIBLE);
                    findViewById(R.id.status).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.config).setVisibility(LinearLayout.GONE);
                }else {
                    Toast.makeText(MainActivity.this,"请先连接设备",Toast.LENGTH_LONG).show();
                }
            }
        });
        findViewById(R.id.devstatus).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if(((TextView)findViewById(R.id.result)).getText().equals("已连接设备")){
                    findViewById(R.id.wificonfig).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.ethconfig).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.status).setVisibility(LinearLayout.VISIBLE);
                    findViewById(R.id.config).setVisibility(LinearLayout.GONE);
                }else {
                    Toast.makeText(MainActivity.this,"请先连接设备",Toast.LENGTH_LONG).show();
                }
            }
        });
        findViewById(R.id.configbutton).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if(((TextView)findViewById(R.id.result)).getText().equals("已连接设备")){
                    findViewById(R.id.wificonfig).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.ethconfig).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.status).setVisibility(LinearLayout.GONE);
                    findViewById(R.id.config).setVisibility(LinearLayout.VISIBLE);
                }else {
                    Toast.makeText(MainActivity.this,"请先连接设备",Toast.LENGTH_LONG).show();
                }
            }
        });

        findViewById(R.id.wifisave).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","setWifiInfo");
                json.put("ssid",((EditText)findViewById(R.id.ssid)).getText());
                json.put("password",((EditText)findViewById(R.id.password)).getText());
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });

        findViewById(R.id.getwifiinfo).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","getWifiInfo");
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });

        findViewById(R.id.getDevStatus).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","getDevStatus");
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        bluetoothReceiver = new BluetoothReceiver();
        registerReceiver(bluetoothReceiver, intentFilter);

        findViewById(R.id.getEthConfig).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","getEthInfo");
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });
        findViewById(R.id.ethsave).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","setEthInfo");
                json.put("type",ethType.getSelectedItem().toString().equals("动态获取")?"DHCP":"STATIC");
                json.put("ip",ethIp.getText()+"/24");
                json.put("gateway",ethGateway.getText());
                json.put("dns1",ethDns1.getText());
                json.put("dns2",ethDns2.getText());
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });
        findViewById(R.id.getConfig).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                JSONObject json = new JSONObject();
                json.put("action","getConfig");
                bluetoothClient.sendMsg(json.toJSONString());
            }
        });
        findViewById(R.id.configSave).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if(clientNo.getText().toString().equals("")||city.getText().toString().equals("")||longitude.getText().toString().equals("")||latitude.getText().toString().equals("")||openTime.getText().toString().equals("")||
                        closeTime.getText().toString().equals("")||adVolume.getText().toString().equals("")||alertVolume.getText().toString().equals("")||orgName.getText().toString().equals("")||intensity.getText().toString().equals("")){
                    Toast.makeText(MainActivity.this,"请先获取配置",Toast.LENGTH_LONG).show();
                }else{
                    info.put("clientNo",clientNo.getText());
                    info.put("city",city.getText());
                    config.put("longitude",longitude.getText());
                    config.put("latitude",latitude.getText());
                    config.put("openTime",openTime.getText());
                    config.put("closeTime",closeTime.getText());
                    config.put("adVolume",adVolume.getText());
                    config.put("alertVolume",alertVolume.getText());
                    config.put("orgName",orgName.getText());
                    config.put("intensity",intensity.getText());
                    JSONObject json = new JSONObject();
                    json.put("action","setConfig");
                    json.put("config",config);
                    json.put("info",info);
                    bluetoothClient.sendMsg(json.toJSONString());
                }
            }
        });

        //定位
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        //定位初始化
        LocationClient mLocationClient = new LocationClient(MainActivity.this);

//通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);

//设置locationClientOption
        mLocationClient.setLocOption(option);

//注册LocationListener监听器
        mLocationClient.registerLocationListener(new BDAbstractLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                if (bdLocation == null){
                    return;
                }
                System.out.println(bdLocation.getLongitude());
                System.out.println(bdLocation.getLatitude());
                longitude.setText(bdLocation.getLongitude()+"");
                latitude.setText(bdLocation.getLatitude()+"");
                GeoCoder mCoder = GeoCoder.newInstance();
                mCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener(){

                    private boolean found;

                    @Override
                    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

                    }

                    @Override
                    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                        if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                            //没有找到检索结果
                            System.out.println("?????????");
                            System.out.println(reverseGeoCodeResult.error);
                            return;
                        } else {
                            //行政区号
                            String cityName = reverseGeoCodeResult.getAddressDetail().city;
                            for (String key:CityKeyUtil.citykeyMap.keySet()) {
                                if(cityName.contains(key)||key.contains(cityName)){
                                    city.setText(CityKeyUtil.getCityKey(key));
                                    found = true;
                                    break;
                                }
                            }
                            if(!found){
                                Toast.makeText(MainActivity.this,"未查询到城市代码，请手动填写",Toast.LENGTH_LONG).show();
                            }else {
                                Toast.makeText(MainActivity.this,"定位成功，已自动填写经纬度、城市编码",Toast.LENGTH_LONG).show();
                            }
                        }
                    }
                });
                mCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude())).newVersion(1).radius(1000000));
//                System.out.println(LocationUtil.getLocation(bdLocation.getLongitude(),bdLocation.getLatitude()));
                mLocationClient.stop();
            }
        });
        findViewById(R.id.gps).setOnClickListener(new OnClickListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onClick(View view) {
                if(lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
//开启地图定位图层
                    mLocationClient.start();
                }else{
                    Toast.makeText(MainActivity.this,"请开启GPS定位",Toast.LENGTH_LONG).show();
                }
            }
        });
    }
    private boolean found;
    public class BluetoothReceiver extends BroadcastReceiver {

        public BluetoothReceiver() {

        }

        //广播接收器，当远程蓝牙设备被发现时，回调函数onReceiver()会被执行
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction(); //得到action
            Log.e("action1=", action);
            BluetoothDevice btDevice=null;  //创建一个蓝牙device对象
            // 从Intent中获取设备对象
            btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            if(BluetoothDevice.ACTION_FOUND.equals(action)){  //发现设备
                Log.e("发现设备:", "["+btDevice.getName()+"]"+":"+btDevice.getAddress());
                if("Android Bluedroid".equals(btDevice.getName())){
                    found = true;
                    System.out.println(btDevice.createBond());
                }
            }else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")){ //再次得到的action，会等于PAIRING_REQUEST

            }else if(action.equals("android.bluetooth.device.action.ACL_CONNECTED")){

            }else if(action.equals("android.bluetooth.device.action.BOND_STATE_CHANGED")){
                switch (btDevice.getBondState()) {
                    case BluetoothDevice.BOND_BONDING:
                        //正在配对
                        System.out.println("正在配对");
                        ((TextView)findViewById(R.id.result)).setText("正在连接设备");
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        //配对结束
                        System.out.println("配对结束");
                        if("Android Bluedroid".equals(btDevice.getName())){
                            ((TextView)findViewById(R.id.result)).setText("已连接设备");
                            bluetoothClient.connect(btDevice);
                        }
                        break;
                    case BluetoothDevice.BOND_NONE:
                        //取消配对/未配对
//                        ((TextView)findViewById(R.id.result)).setText("未连接设备");
                        System.out.println("取消配对/未配对");
                    default:
                        break;
                }
            }else if(action.equals("android.bluetooth.adapter.action.DISCOVERY_FINISHED")){
                if(!found){
                    ((TextView)findViewById(R.id.result)).setText("未发现设备");
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消广播接收者的注册
        unregisterReceiver(bluetoothReceiver);
        bluetoothClient.close();
    }

    private void checkBTPermission() {
        Log.d("TAG", "checkBTPermission: Start");
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
            int permissionCheck = 0;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                permissionCheck = this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
                permissionCheck += this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
                if(permissionCheck != 0){
                    System.out.println("BLUETOOTH_PRIVILEGED");
                    this.requestPermissions(new String[]{
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                    }, 1001); //any number
                }else{
                    Log.d("TAG",
                            "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
                }
            }

        }
        Log.d("TAG", "checkBTPermission: Finish");
    }

    //通过反射来调用BluetoothDevice.removeBond取消设备的配对
    private void unpairDevice(BluetoothDevice device) {
        try {
            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
            m.setAccessible(true);
            m.invoke(device, (Object[]) null);
        } catch (Exception e) {
            Log.e("ble",e.toString());
        }
    }
}